local ADDON_NAME = ...

local GearTable = CreateFrame("Frame", "GearTableFrame")
GearTable.items = {}
GearTable.rows = {}
GearTable.sortKey = "quality"
GearTable.sortAsc = false

local GetItemStatsCompat = C_Item and C_Item.GetItemStats or GetItemStats

local QUALITY_NAMES = {
    [0] = "Poor",
    [1] = "Common",
    [2] = "Uncommon",
    [3] = "Rare",
    [4] = "Epic",
    [5] = "Legendary",
}

local SLOT_LABELS = {
    INVTYPE_HEAD = "Head",
    INVTYPE_NECK = "Neck",
    INVTYPE_SHOULDER = "Shoulder",
    INVTYPE_CHEST = "Chest",
    INVTYPE_ROBE = "Chest",
    INVTYPE_WAIST = "Waist",
    INVTYPE_LEGS = "Legs",
    INVTYPE_FEET = "Feet",
    INVTYPE_WRIST = "Wrist",
    INVTYPE_HAND = "Hands",
    INVTYPE_FINGER = "Finger",
    INVTYPE_TRINKET = "Trinket",
    INVTYPE_CLOAK = "Back",
    INVTYPE_WEAPON = "One-Hand",
    INVTYPE_SHIELD = "Shield",
    INVTYPE_2HWEAPON = "Two-Hand",
    INVTYPE_WEAPONMAINHAND = "Main Hand",
    INVTYPE_WEAPONOFFHAND = "Off Hand",
}

local SLOT_ORDER = {
    Head=1, Neck=2, Shoulder=3, Back=4, Chest=5,
    Wrist=6, Hands=7, Waist=8, Legs=9, Feet=10,
    Finger=11, Trinket=12, ["Main Hand"]=13, ["Off Hand"]=14,
    ["One-Hand"]=15, ["Two-Hand"]=16, Shield=17
}

local function SafeColorText(text, quality)
    local color = ITEM_QUALITY_COLORS[quality or 1]
    if not color then return text end

    local r = math.floor(color.r * 255 + 0.5)
    local g = math.floor(color.g * 255 + 0.5)
    local b = math.floor(color.b * 255 + 0.5)

    return string.format("|cff%02x%02x%02x%s|r", r, g, b, text)
end

local function GetQualityName(q)
    return QUALITY_NAMES[q or 1] or "Unknown"
end

local function GetSlotLabel(loc)
    return SLOT_LABELS[loc] or loc or "?"
end

local function GetContainerNumSlotsCompat(bag)
    if C_Container then return C_Container.GetContainerNumSlots(bag) end
    return GetContainerNumSlots(bag)
end

local function GetContainerItemLinkCompat(bag, slot)
    if C_Container then return C_Container.GetContainerItemLink(bag, slot) end
    return GetContainerItemLink(bag, slot)
end

local function IsWantedItem(link)
    local _, _, _, _, _, itemType, _, _, equipLoc = GetItemInfo(link)
    return equipLoc and (itemType == ARMOR or itemType == WEAPON)
end

local function BuildStatSummary(link)
    local stats = GetItemStatsCompat and GetItemStatsCompat(link)
    if not stats then return "" end

    local function val(key) return stats[key] end

    local parts = {}

    local function add(v, label)
        if v and v ~= 0 then
            table.insert(parts, string.format("%+d %s", v, label))
        end
    end

    add(val("ITEM_MOD_STAMINA_SHORT") or val("ITEM_MOD_STAMINA"), "Stam")
    add(val("ITEM_MOD_STRENGTH_SHORT") or val("ITEM_MOD_STRENGTH"), "Str")
    add(val("ITEM_MOD_AGILITY_SHORT") or val("ITEM_MOD_AGILITY"), "Agi")
    add(val("ITEM_MOD_DEFENSE_SKILL_RATING") or val("DEFENSE"), "Def")
    add(val("ITEM_MOD_HIT_RATING") or val("ITEM_MOD_HIT_MELEE_RATING"), "Hit")
    add(val("ITEM_MOD_CRIT_RATING") or val("ITEM_MOD_CRIT_MELEE_RATING"), "Crit")
    add(val("ITEM_MOD_DODGE_RATING"), "Dodge")
    add(val("ITEM_MOD_PARRY_RATING"), "Parry")
    add(val("ITEM_MOD_BLOCK_RATING"), "Block")
    add(val("ITEM_MOD_ATTACK_POWER"), "AP")

    return table.concat(parts, ", ")
end

local function Compare(a, b)
    if GearTable.sortKey == "quality" then
        if a.quality ~= b.quality then
            return a.quality > b.quality
        end
    elseif GearTable.sortKey == "slot" then
        if a.slotOrder ~= b.slotOrder then
            return a.slotOrder < b.slotOrder
        end
    elseif GearTable.sortKey == "name" then
        return a.name < b.name
    end

    return a.name < b.name
end

local function CreateWindow()
    local f = CreateFrame("Frame", "GearTableMain", UIParent, "BackdropTemplate")
    f:SetSize(900, 500)
    f:SetPoint("CENTER")
    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)
    f:SetBackdrop({bgFile="Interface/Tooltips/UI-Tooltip-Background"})
    f:SetBackdropColor(0,0,0,0.9)

    local title = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
    title:SetPoint("TOPLEFT",10,-10)
    title:SetText("GearTable")

    local scroll = CreateFrame("ScrollFrame", nil, f, "UIPanelScrollFrameTemplate")
    scroll:SetPoint("TOPLEFT",10,-40)
    scroll:SetPoint("BOTTOMRIGHT",-30,10)

    local content = CreateFrame("Frame", nil, scroll)
    content:SetSize(1,1)
    scroll:SetScrollChild(content)

    GearTable.window = f
    GearTable.content = content
end

function GearTable:Scan()
    wipe(self.items)

    for bag=0,4 do
        for slot=1,(GetContainerNumSlotsCompat(bag) or 0) do
            local link = GetContainerItemLinkCompat(bag,slot)
            if link and IsWantedItem(link) then
                local name, _, quality, _, _, _, _, _, equipLoc = GetItemInfo(link)

                table.insert(self.items,{
                    name=name,
                    quality=quality or 1,
                    qualityName=GetQualityName(quality),
                    slot=GetSlotLabel(equipLoc),
                    slotOrder=SLOT_ORDER[GetSlotLabel(equipLoc)] or 999,
                    stats=BuildStatSummary(link),
                    link=link
                })
            end
        end
    end
end

function GearTable:Render()
    table.sort(self.items, Compare)

    for i,row in ipairs(self.rows) do row:Hide() end

    for i,item in ipairs(self.items) do
        local row = self.rows[i] or CreateFrame("Button", nil, self.content)
        self.rows[i] = row

        row:SetSize(850,20)
        row:SetPoint("TOPLEFT",0,-(i-1)*22)

        local text = row.text or row:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall")
        row.text = text
        text:SetAllPoints()

        text:SetText(
            SafeColorText(item.name,item.quality) ..
            " | " .. item.qualityName ..
            " | " .. item.slot ..
            " | " .. (item.stats ~= "" and item.stats or "-")
        )

        row:SetScript("OnEnter", function()
            GameTooltip:SetOwner(row,"ANCHOR_RIGHT")
            GameTooltip:SetHyperlink(item.link)
        end)
        row:SetScript("OnLeave", GameTooltip_Hide)

        row:Show()
    end
end

function GearTable:Toggle()
    if not self.window then CreateWindow() end

    if self.window:IsShown() then
        self.window:Hide()
    else
        self:Scan()
        self:Render()
        self.window:Show()
    end
end

SLASH_GEARTABLE1="/gt"
SLASH_GEARTABLE2="/geartable"
SlashCmdList["GEARTABLE"]=function() GearTable:Toggle() end
